package cn.fuxi2022.core.utils;

import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;


@Component
@Slf4j
public class SmsUtils {

    /**
     * 固定域名，通常无需指定域名，但访问金融区的服务时必须手动指定域名
     * 固定：sms.tencentcloudapi.com
     */
    @Value("${cloud.tencent.sms.appUrl}")
    private String appurl = "sms.tencentcloudapi.com";

    /**
     * 应用的SDK AppID（应用是方便设置个性化管理短信发送任务）
     * 短信控制台 ---> 应用管理 ---> 应用列表 ---> 应用的SDK AppID
     */
    @Value("${cloud.tencent.sms.appId}")
    private String SDKAppID;

    /**
     * 应用的SDK App Key（需要保密）
     * 短信控制台 ---> 应用管理 ---> 应用列表 ---> 应用的App Key
     */
    @Value("${cloud.tencent.sms.appKey}")
    private String SDKAppKey;

    /**
     * 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名
     * 国内短信 ---> 签名管理 ---> 名内容
     * 直接写中文，不是ID
     */
    @Value("${cloud.tencent.sms.signName}")
    private String SignName;

    /**
     * 登录验证码模板
     * 模板 ID: 必须填写已审核通过的模板 ID
     * 短信控制台 ---> 国内短信 ---> 正文模板管理
     */
    @Value("${cloud.tencent.sms.templateId_code}")
    private String templateId_code;

    /**
     * 支付成功模板
     * 模板 ID: 必须填写已审核通过的模板 ID
     * 短信控制台 ---> 国内短信 ---> 正文模板管理
     */
    @Value("${cloud.tencent.sms.templateId_order}")
    private String templateId_order;

    /**
     * 用户的SecretId（需要保密，因为主用户可以访问其他访服务的任意接口，建议设置子账户）
     * 访问管理控制台 ---> 用户列表 ---> 选择用户 ---> API 密钥
     */
    @Value("${cloud.tencent.user.secretId}")
    private String secretId;

    /**
     * 用户的SecretKey（需要保密，因为主用户可以访问其他访服务的任意接口，建议设置子账户）
     * 访问管理控制台 ---> 用户列表 ---> 选择用户 ---> API 密钥
     */
    @Value("${cloud.tencent.user.secretKey}")
    private String secretKey;

    /**
     * 获取 腾讯云短信 的client对象
     *
     * @return client对象
     */
    public SmsClient getSmsClient() {
        log.info(secretId);
        log.info(secretKey);
        // 实例化一个认证对象，入参需要传入腾讯云账户secretId，secretKey,此处还需注意密钥对的保密
        // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
        Credential cred = new Credential(secretId, secretKey);
        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint(appurl);
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        // 实例化要请求产品的client对象,clientProfile是可选的
        return new SmsClient(cred, "ap-guangzhou", clientProfile);
    }


    /**
     * 发送手机验证码的方法
     *
     * @param phone            手机号
     * @param templateId       使用的模板ID
     * @param templateParamSet 模板参数（需要与模板对应）
     * @return true 成功 false 失败
     */
    public boolean sendMsg(String phone, String templateId, String[] templateParamSet) {

        // 获取 腾讯云短信 的client对象
        SmsClient client = getSmsClient();

        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            SendSmsRequest req = new SendSmsRequest();
            //手机号数组
            String[] phoneNumberSet1 = {"+86" + phone};
            req.setPhoneNumberSet(phoneNumberSet1);

            //短信应用id   “SmsSdkAppId”
            req.setSmsSdkAppId(SDKAppID);
            //签名内容   “SignName”
            req.setSignName(SignName);
            //正文模板id   “TemplateId”
            req.setTemplateId(templateId);

            //模板参数
            req.setTemplateParamSet(templateParamSet);

            // 返回的resp是一个SendSmsResponse的实例，与请求对象对应
            SendSmsResponse resp = client.SendSms(req);
            // 输出json格式的字符串回包
            // System.out.println(SendSmsResponse.toJsonString(resp));

            // 获取发送结果
            SendStatus[] sendStatusSet = resp.getSendStatusSet();
            // log.info(sendStatusSet[0].getCode());
            // nmd,是大写的O，小写的k
            return "Ok".equals(sendStatusSet[0].getCode());

        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 发送手机验证码的方法
     *
     * @param phone 手机号
     * @param code  验证码
     * @param time  有效时间
     * @return true 成功 false 失败
     */
    public boolean sendCaptcha(String phone, String code, String time) {
        // 构建模板参数,验证码与有效时间数组
        String[] templateParamSet = {code, time};
        return sendMsg(phone, templateId_code, templateParamSet);
    }

    /**
     * 发送订单成功的方法
     *
     * @param phone   手机号
     * @param price   订单金额（没有校验订单号是否合法，传过来是什么，就发送什么）
     * @param orderNo 订单号（没有校验订单号是否合法，传过来是什么，就发送什么）
     * @param time    时间（没有格式化，传过来是什么，就发送什么）
     */
    public void sendOrderSuccess(String phone, String price, String orderNo, String time) {
        // 构建模板参数,验证码与有效时间数组
        String[] templateParamSet = {price, orderNo, time};
        sendMsg(phone, templateId_order, templateParamSet);
    }

}